using MediatR;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using SumerCoreDevOps.Application.Users.Commands;
using SumerCoreDevOps.Application.Users.Queries;
using SumerCoreDevOps.Domain.Entities;
using SumerCoreDevOps.Application.Dtos.Requests.Users;
namespace SumerCoreDevOps.ControlApi.Controllers;

/// <summary>
/// 用户管理 API
/// 提供用户的增删改查、密码管理、锁定/解锁等功能
/// </summary>
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class UserController : ControllerBase
{
    private readonly IMediator _mediator;
    private readonly ILogger<UserController> _logger;

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="mediator">MediatR 中介者</param>
    /// <param name="logger">日志记录器</param>
    public UserController(IMediator mediator, ILogger<UserController> logger)
    {
        _mediator = mediator;
        _logger = logger;
    }

    /// <summary>
    /// 获取所有用户列表
    /// </summary>
    /// <returns>返回包含所有用户的列表,每个用户包括ID、用户名、邮箱、显示名称、是否锁定、创建时间等信息;如果发生错误则返回500状态码和错误详情</returns>
    /// <response code="200">成功返回用户列表</response>
    /// <response code="500">服务器内部错误</response>
    [HttpGet]
    [ProducesResponseType(typeof(List<User>), 200)]
    public async Task<ActionResult<List<User>>> GetAllUsers()
    {
        try
        {
            var users = await _mediator.Send(new GetAllUsersQuery());
            return Ok(users);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取用户列表失败");
            return StatusCode(500, new { message = "获取用户列表失败", error = ex.Message });
        }
    }

    /// <summary>
    /// 获取用户详细信息（包含角色）
    /// </summary>
    /// <param name="userId">用户ID</param>
    /// <returns>返回包含用户基本信息和该用户拥有的所有角色列表的对象;如果用户不存在则返回404状态码和提示信息;发生错误时返回500状态码和错误详情</returns>
    /// <response code="200">成功返回用户信息</response>
    /// <response code="404">用户不存在</response>
    /// <response code="500">服务器内部错误</response>
    [HttpGet("{userId}")]
    [ProducesResponseType(typeof(object), 200)]
    public async Task<ActionResult<object>> GetUserWithRoles(long userId)
    {
        try
        {
            var userInfo = await _mediator.Send(new GetUserWithRolesQuery(userId));
            if (userInfo == null)
            {
                return NotFound(new { message = "用户不存在" });
            }

            return Ok(userInfo);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取用户详细信息失败: UserId={UserId}", userId);
            return StatusCode(500, new { message = "获取用户信息失败", error = ex.Message });
        }
    }

    /// <summary>
    /// 获取用户权限列表
    /// </summary>
    /// <param name="userId">用户ID</param>
    /// <returns>返回用户通过所属角色继承的所有权限代码的字符串列表;如果用户没有任何角色或角色没有权限则返回空列表;发生错误时返回500状态码和错误详情</returns>
    /// <response code="200">成功返回权限列表</response>
    /// <response code="500">服务器内部错误</response>
    [HttpGet("{userId}/permissions")]
    [ProducesResponseType(typeof(List<string>), 200)]
    public async Task<ActionResult<List<string>>> GetUserPermissions(long userId)
    {
        try
        {
            var permissions = await _mediator.Send(new GetUserPermissionsQuery(userId));
            return Ok(permissions);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取用户权限失败: UserId={UserId}", userId);
            return StatusCode(500, new { message = "获取用户权限失败", error = ex.Message });
        }
    }

    /// <summary>
    /// 创建新用户
    /// </summary>
    /// <param name="request">创建用户请求</param>
    /// <returns>返回201状态码和新创建的用户完整信息对象,包括自动生成的用户ID、用户名、邮箱、显示名称、创建时间等字段(密码已加密不返回);如果用户名或邮箱已存在则返回400状态码和错误提示;发生其他错误时返回500状态码和错误详情</returns>
    /// <response code="201">成功创建用户</response>
    /// <response code="400">请求参数无效</response>
    /// <response code="500">服务器内部错误</response>
    [HttpPost]
    [ProducesResponseType(typeof(User), 201)]
    public async Task<ActionResult<User>> CreateUser([FromBody] CreateUserRequest request)
    {
        try
        {
            var user = await _mediator.Send(new CreateUserCommand(
                request.Username,
                request.Password,
                request.Email,
                request.DisplayName,
                request.CreatedBy
            ));

            return CreatedAtAction(nameof(GetUserWithRoles), new { userId = user.Id }, user);
        }
        catch (InvalidOperationException ex)
        {
            return BadRequest(new { message = ex.Message });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "创建用户失败: Username={Username}", request.Username);
            return StatusCode(500, new { message = "创建用户失败", error = ex.Message });
        }
    }

    /// <summary>
    /// 修改用户密码
    /// </summary>
    /// <param name="userId">用户ID</param>
    /// <param name="request">修改密码请求</param>
    /// <returns>返回200状态码和成功提示信息;如果旧密码错误则返回400状态码和错误提示;如果用户不存在则返回404状态码;发生错误时返回500状态码和错误详情</returns>
    /// <response code="200">密码修改成功</response>
    /// <response code="400">旧密码错误或请求参数无效</response>
    /// <response code="404">用户不存在</response>
    /// <response code="500">服务器内部错误</response>
    [HttpPut("{userId}/password")]
    public async Task<ActionResult> ChangePassword(long userId, [FromBody] ChangePasswordRequest request)
    {
        try
        {
            await _mediator.Send(new ChangePasswordCommand(
                userId,
                request.OldPassword,
                request.NewPassword
            ));

            return Ok(new { message = "密码修改成功" });
        }
        catch (InvalidOperationException ex)
        {
            return BadRequest(new { message = ex.Message });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "修改密码失败: UserId={UserId}", userId);
            return StatusCode(500, new { message = "修改密码失败", error = ex.Message });
        }
    }

    /// <summary>
    /// 重置用户密码（管理员操作）
    /// </summary>
    /// <param name="userId">用户ID</param>
    /// <param name="request">重置密码请求</param>
    /// <returns>返回200状态码、成功提示信息和自动生成的新密码;如果用户不存在则返回404状态码;发生错误时返回500状态码和错误详情</returns>
    /// <response code="200">密码重置成功</response>
    /// <response code="400">请求参数无效</response>
    /// <response code="404">用户不存在</response>
    /// <response code="500">服务器内部错误</response>
    [HttpPut("{userId}/reset-password")]
    public async Task<ActionResult> ResetPassword(long userId, [FromBody] ResetPasswordRequest request)
    {
        try
        {
            var newPassword = await _mediator.Send(new ResetPasswordCommand(
                userId,
                request.OperatedBy
            ));

            return Ok(new { message = "密码重置成功", newPassword });
        }
        catch (InvalidOperationException ex)
        {
            return BadRequest(new { message = ex.Message });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "重置密码失败: UserId={UserId}", userId);
            return StatusCode(500, new { message = "重置密码失败", error = ex.Message });
        }
    }

    /// <summary>
    /// 锁定用户
    /// </summary>
    /// <param name="userId">用户ID</param>
    /// <param name="request">锁定用户请求</param>
    /// <returns>返回200状态码和成功提示信息;如果用户不存在则返回404状态码;如果用户已被锁定则返回400状态码和提示信息;发生错误时返回500状态码和错误详情</returns>
    /// <response code="200">用户锁定成功</response>
    /// <response code="400">请求参数无效</response>
    /// <response code="404">用户不存在</response>
    /// <response code="500">服务器内部错误</response>
    [HttpPut("{userId}/lock")]
    public async Task<ActionResult> LockUser(long userId, [FromBody] LockUserRequest request)
    {
        try
        {
            await _mediator.Send(new LockUserCommand(
                userId,
                request.Reason ?? "未提供原因",
                request.OperatedBy
            ));

            return Ok(new { message = "用户已锁定" });
        }
        catch (InvalidOperationException ex)
        {
            return BadRequest(new { message = ex.Message });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "锁定用户失败: UserId={UserId}", userId);
            return StatusCode(500, new { message = "锁定用户失败", error = ex.Message });
        }
    }

    /// <summary>
    /// 解锁用户
    /// </summary>
    /// <param name="userId">用户ID</param>
    /// <param name="request">解锁用户请求</param>
    /// <returns>返回200状态码和成功提示信息;如果用户不存在则返回404状态码;如果用户未被锁定则返回400状态码和提示信息;发生错误时返回500状态码和错误详情</returns>
    /// <response code="200">用户解锁成功</response>
    /// <response code="400">请求参数无效</response>
    /// <response code="404">用户不存在</response>
    /// <response code="500">服务器内部错误</response>
    [HttpPut("{userId}/unlock")]
    public async Task<ActionResult> UnlockUser(long userId, [FromBody] UnlockUserRequest request)
    {
        try
        {
            await _mediator.Send(new UnlockUserCommand(
                userId,
                request.OperatedBy
            ));

            return Ok(new { message = "用户已解锁" });
        }
        catch (InvalidOperationException ex)
        {
            return BadRequest(new { message = ex.Message });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "解锁用户失败: UserId={UserId}", userId);
            return StatusCode(500, new { message = "解锁用户失败", error = ex.Message });
        }
    }

    /// <summary>
    /// 验证用户凭据（用于登录）
    /// </summary>
    /// <param name="request">登录凭据</param>
    /// <returns>如果验证成功返回200状态码、成功提示信息和用户完整信息对象;如果用户名或密码错误则返回401状态码;如果用户已被锁定则返回403状态码和锁定原因;发生错误时返回500状态码和错误详情</returns>
    /// <response code="200">验证成功</response>
    /// <response code="401">用户名或密码错误</response>
    /// <response code="403">用户已被锁定</response>
    /// <response code="500">服务器内部错误</response>
    [HttpPost("validate")]
    public async Task<ActionResult<object>> ValidateCredentials([FromBody] ValidateCredentialsRequest request)
    {
        try
        {
            var result = await _mediator.Send(new ValidateCredentialsCommand(
                request.Username,
                request.Password
            ));

            if (result == null)
            {
                return Unauthorized(new { message = "用户名或密码错误" });
            }

            // 检查用户是否被锁定
            if (result.IsLocked)
            {
                return StatusCode(403, new { message = "用户已被锁定", reason = result.LockReason });
            }

            return Ok(new
            {
                message = "验证成功",
                user = result
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "验证凭据失败: Username={Username}", request.Username);
            return StatusCode(500, new { message = "验证凭据失败", error = ex.Message });
        }
    }
}
